package chapter5;


import org.junit.Test;

import java.util.Arrays;

import java.util.List;
import java.util.Optional;
import java.util.function.IntSupplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;


public class TransactionTest {
    @Test
    public void Test() {
        Trader raoul = new Trader("Raoul", "Cambridge");
        Trader mario = new Trader("Mario","Milan");
        Trader alan = new Trader("Alan","Cambridge");
        Trader brian = new Trader("Brian","Cambridge");
        List<Transaction> transactions = Arrays.asList(
                new Transaction(brian, 2011, 300),
                new Transaction(raoul, 2012, 1000),
                new Transaction(raoul, 2011, 400),
                new Transaction(mario, 2012, 710),
                new Transaction(mario, 2012, 700),
                new Transaction(alan, 2012, 950)
        );
    List<Transaction> tr2011 =
                transactions.stream()
                .filter(transaction -> transaction.getYear()==2011)
                .sorted(comparing(Transaction::getValue))
                .collect(toList());
    System.out.println(tr2011);

    List<String> countrys =
                    transactions.stream()
                    .map(Transaction::getTrader)
                    .map(Trader::getCity)
                    .distinct()
                    .collect(toList());
    System.out.println(countrys);

    //3
    List<Trader> cambridgeTraders =
                    transactions.stream()
                    .map(Transaction::getTrader)
                    .filter(trader -> "Cambridge".equals(trader.getCity()) )
                    .sorted(comparing(Trader::getName))
                    .collect(toList());
    System.out.println(cambridgeTraders);

    //4
    String traderNames =
                    transactions.stream()
                    .map(transaction->transaction.getTrader().getName())
                    .sorted()
                    .reduce("",(n1,n2) -> n1+n2);
    System.out.println(traderNames);
    //5
     Boolean isMilan = transactions.stream()
                       .anyMatch(transaction->"Milan".equals(transaction.getTrader().getCity()));
     System.out.println(isMilan);

    //6
                transactions.stream()
                                    .filter(transaction -> "Cambridge".equals(transaction.getTrader().getCity()))
                                    .map(Transaction::getValue)
                                    .forEach(System.out::println);

     //7
     Optional<Integer> highestValue =
                transactions.stream()
                        .map(Transaction::getValue)
                        .reduce(Integer::max);
     System.out.println(highestValue);

     //8
        Optional<Integer> minValue =
                transactions.stream()
                        .map(Transaction::getValue)
                        .reduce(Integer::min);
        System.out.println(minValue);
/*
(1) 找出2011年发生的所有交易，并按交易额排序（从低到高）。
(2) 交易员都在哪些不同的城市工作过？
(3) 查找所有来自于剑桥的交易员，并按姓名排序。
(4) 返回所有交易员的姓名字符串，按字母顺序排序。
(5) 有没有交易员是在米兰工作的？
(6) 打印生活在剑桥的交易员的所有交易额。
(7) 所有交易中，最高的交易额是多少？
(8) 找到交易额最小的交易。*/
        Stream<int[]> pythagoreanTriples = IntStream.rangeClosed(1,100).boxed()
                    .flatMap(a->
                            IntStream.rangeClosed(a,100)
                            .filter(b->Math.sqrt(a*a+b*b)%1 == 0)
                            .mapToObj(b ->
                                    new int[]{a,b,(int)Math.sqrt(a*a+b*b)})


                    );

        pythagoreanTriples.limit(5)
                .forEach(t ->
                        System.out.println(t[0] + ", " + t[1] + ", " + t[2]));




        Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
        stream.map(String::toUpperCase).forEach(System.out::println);

        int[] numbers = {2,3,5,7,11,13};
        int sum = Arrays.stream(numbers).sum();

        Stream.iterate(0, n -> n + 2)
                .limit(10)
                .forEach(System.out::println);


       Stream.iterate(new int[]{0,1},
               t->new int[]{t[1],t[0]+t[1]})
               .limit(10)
               .map(t->t[0])
               .forEach(System.out::println);
    /*Stream.iterate(new int[]{0, 1},
    t -> new int[]{t[1],t[0] + t[1]})
    .limit(10)
    .map(t -> t[0])
    .forEach(System.out::println);*/
        IntSupplier fib = new IntSupplier(){
            private int previous = 0;
            private int current = 1;
            public int getAsInt(){
                int oldPrevious = this.previous;
                int nextValue = this.previous + this.current;
                this.previous = this.current;
                this.current = nextValue;
                return oldPrevious;
            }
        };
        IntStream.generate(fib).limit(10).forEach(System.out::println);
    }

}
